package com.cornergj.chat.webstock;

import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpSession;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import net.sf.json.JSONArray;

import org.json.JSONObject;

import com.cornergj.response.JsonResult;
@ServerEndpoint(value="/websocketoto",configurator=GetHttpSessionConfigurator.class)
public class MyWebSocketOtO{
	//静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;
    
    private static String adminSessionId="";
    private static Session adminsession=null;
    //concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话，可以使用Map来存放，其中Key可以为用户标识
    public static ConcurrentMap<String,MyWebSocketOtO> webSocketMap = new ConcurrentHashMap<String,MyWebSocketOtO>();
    
    private static ConcurrentMap<Session,Session> webmap=new ConcurrentHashMap<Session,Session>();
    
    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;
     
    /**
     * 连接建立成功调用的方法
     * @param session  可选的参数。session为与某个客户端的连接会话，需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(Session session,EndpointConfig config){
        this.session = session;
        HttpSession httpSession= (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        if(adminSessionId.equals("")){
        	webSocketMap.put(session.getId().toString(), this);
        }else{
        	if(adminSessionId.equals(httpSession.getId().toString())){
        		adminsession=session;
        		webSocketMap.put(adminsession.getId(), this); 
        	}else{
        		webSocketMap.put(session.getId().toString(), this);
        	}
        }
        addOnlineCount();           //在线数加1
    }
     
    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(Session session){
    	if(adminsession!=null){
    		if(session.getId().equals(adminsession.getId())){
    			adminsession=null;
        	}else{
            	MyWebSocketOtO item=webSocketMap.get(adminsession.getId());
               	 if(item!=null){
               	 	try{
               	 		JsonResult result=new JsonResult();
               	 		result.setStatus(2);//表示删除
               	 		result.setData(session.getId());
               	 		JSONArray array = JSONArray.fromObject(result);
               	 		item.sendMessage(array.toString());//推送到管理员端
               	 	}catch(Exception e){
               	 		e.printStackTrace();
               	 	}
               	 }
        	}
    	}
    	webSocketMap.remove(session.getId().toString());  //从set中删除
		subOnlineCount();           //在线数减1    
    }
     
    /**
     * 收到客户端消息后调用的方法
     * @param message 客户端发送过来的消息
     * @param session 可选的参数
     */
    @OnMessage
    public void onMessage(String message, Session session) {
         if(adminsession==null){//管理员没上线
        	MyWebSocketOtO item=webSocketMap.get(session.getId().toString());
            try {
    			item.sendMessage("您好，客服现在不在线上，请稍后重试");
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
         }else{//管理员在线
        	 if(session.getId().equals(adminsession.getId())){//管理员发来的消息
        		 String[] adminSendMsg=message.split("\\^\\&\\*\\#");
        		 MyWebSocketOtO item=webSocketMap.get(adminSendMsg[0]);//获取目标推送用户
        		 if(item!=null){
        			 try {
						item.sendMessage(adminSendMsg[1]);
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
        		 }
        	 }else{
        		 MyWebSocketOtO item=webSocketMap.get(adminsession.getId());//要发送给管理员的消息
            	 if(item!=null){
            		 try {
            			JsonResult result=new JsonResult();
            			result.setStatus(1);//表示发送消息
            			Map<String,Object> webStockMap=new HashMap<String,Object>();
            			webStockMap.put("message", message);//消息
            			webStockMap.put("targetsession", session.getId());//目标对象
            			result.setExtra(webStockMap);
            			JSONArray array = JSONArray.fromObject(result);
            			item.sendMessage(array.toString());//推送到管理员端
             		} catch (Exception e) {
             			// TODO Auto-generated catch block
             			e.printStackTrace();
             		}
            	 }
        	 }
         }
    }
     
    /**
     * 发生错误时调用
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error){
    	System.out.println("发生错误");
    	if(adminsession!=null && !session.getId().equals(adminsession.getId())){
    		MyWebSocketOtO item=webSocketMap.get(adminsession.getId());
       	 	if(item!=null){
       	 		try{
       	 			JsonResult result=new JsonResult();
       	 			result.setStatus(2);//表示删除
       	 			result.setData(session.getId());
       	 			JSONArray array = JSONArray.fromObject(result);
       	 			item.sendMessage(array.toString());//推送到管理员端
       	 		}catch(Exception e){
       	 			e.printStackTrace();
       	 		}
       	 	}
    	}
        error.printStackTrace();
    }
     
    /**
     * 这个方法与上面几个方法不一样。没有用注解，是根据自己需要添加的方法。
     * @param message
     * @throws IOException
     */
    public void sendMessage(String message) throws IOException{
        this.session.getBasicRemote().sendText(message);
    }
 
    public static synchronized int getOnlineCount() {
        return onlineCount;
    }
 
    public static synchronized void addOnlineCount() {
        MyWebSocketOtO.onlineCount++;
    }
     
    public static synchronized void subOnlineCount() {
        MyWebSocketOtO.onlineCount--;
    }

	public static String getAdminSessionId() {
		return adminSessionId;
	}

	public static void setAdminSessionId(String adminSessionId) {
		MyWebSocketOtO.adminSessionId = adminSessionId;
	}
    
    
}
